package com.example.data.factory.service.service.Impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.data.factory.common.Dto.*;
import com.example.data.factory.common.common.StringConstant;
import com.example.data.factory.common.result.PageVO;
import com.example.data.factory.common.result.R;
import com.example.data.factory.common.util.CodeGeneratorUtil;
import com.example.data.factory.common.util.CommonUtil;
import com.example.data.factory.entity.entity.DataStandard;
import com.example.data.factory.entity.entity.Dict;
import com.example.data.factory.entity.entity.DictData;
import com.example.data.factory.mapper.mapper.DataStandardMapper;
import com.example.data.factory.mapper.mapper.DictDataMapper;
import com.example.data.factory.mapper.mapper.DictMapper;
import com.example.data.factory.service.service.DataStandardService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;

/**
 * <p>
 * 数据标准目录 服务实现类
 * </p>
 *
 * @author lhy
 * @since 2025-03-03
 */
@Service
public class DataStandardServiceImpl extends ServiceImpl<DataStandardMapper, DataStandard> implements DataStandardService {
    @Resource
    private DataStandardMapper dataStandardMapper;
    @Resource
    private DictMapper dictMapper;
    @Resource
    private DictDataMapper dictDataMapper;
    @Resource
    private CommonUtil commonUtil;

    @Override
    public R<DataStandard> search(SearchDtaStandardDto searchDtaStandardDto) {
        // 创建分页对象
        Page<DataStandard> page = new Page<> ( searchDtaStandardDto.getPageNumber (), searchDtaStandardDto.getPageSize () );

        // 构建查询条件
        LambdaQueryWrapper<DataStandard> wrapper = new LambdaQueryWrapper<> ();

        if (StringUtils.isNotBlank ( searchDtaStandardDto.getInstitution () )) {
            wrapper.eq ( DataStandard::getInstitution, searchDtaStandardDto.getInstitution () );
        }
        if (searchDtaStandardDto.getStatus () != null) {
            wrapper.eq ( DataStandard::getStatus, searchDtaStandardDto.getStatus () );
        }
        if (StringUtils.isNotBlank ( searchDtaStandardDto.getStandardCode () )) {
            wrapper.eq ( DataStandard::getStandardCode, searchDtaStandardDto.getStandardCode () );
        }
        if (StringUtils.isNotBlank ( searchDtaStandardDto.getChineseName () )) {
            wrapper.like ( DataStandard::getChineseName, searchDtaStandardDto.getChineseName () );
        }
        if (StringUtils.isNotBlank ( searchDtaStandardDto.getEnglishName () )) {
            wrapper.like ( DataStandard::getEnglishName, searchDtaStandardDto.getEnglishName () );
        }
        wrapper.eq ( DataStandard::getDeleted, 0 ); // 确保未删除的数据

        // 执行查询
        Page<DataStandard> pageResult = this.page ( page, wrapper );

        // 将MyBatis-Plus的Page对象转换为自定义的PageVO对象
        PageVO<DataStandard> pageVO = new PageVO<> ();
        BeanUtil.copyProperties ( pageResult, pageVO );

        return R.Success ( pageVO );
    }

    @Override
    public R<DataStandard> insert(InsertDataStandardDto insertDataStandardDto) {
        DataStandard dataStandard = new DataStandard ();
        List<DataStandard> list1 = this.list ();
        BeanUtil.copyProperties ( insertDataStandardDto, dataStandard );
        dataStandard.setCreateTime ( LocalDateTime.now () );
        dataStandard.setUpdateTime ( LocalDateTime.now () );
        Integer id = dataStandardMapper.selctMaxId ();
        String datastandrdcode = CodeGeneratorUtil.generateCode ( "ZB", id );
        dataStandard.setStandardCode ( datastandrdcode );
        dataStandard.setCreateBy ( "管理员" );
        //当用户输入的数据类型为枚举时,就可以编辑数据标准目录表里的码表名称，将其选择的码表名称放入DictName字段里
        if (dataStandard.getDataType ().equals ( "Enum" )) {
            //拿到dict表里的所有码表的名称和码表编号
            List<Dict> list = dictMapper.list ();
            // 假设前端传来了一个名为selectedDictName的属性，表示用户选择的码表名称
            String selectedDictName = dataStandard.getDictName (); // 这里假设有一个获取用户选择的方法
            Optional<Dict> selectDictOpt = list.stream ().filter ( dict -> dict.getDictName ().equals ( selectedDictName ) )
                    .findFirst ();
            if (selectDictOpt.isPresent ()) {
                Dict select = selectDictOpt.get ();
                dataStandard.setDictName ( select.getDictName () );
                dataStandard.setDictId ( Long.valueOf ( select.getDictId () ) );
                dataStandard.setDictCode ( select.getDictCode () );
                // 额外检查：确保dictId在dict_data表中存在
                if (!isDictIdValid ( Long.valueOf ( select.getDictId () ) )) {
                    return R.Failed ( StringConstant.DICTNOTEXISTS );
                }
            } else {
                return R.Failed ( StringConstant.DICTNOTEXICTS );
            }
        }
        if (list1.stream ().anyMatch ( data -> data.getChineseName ().equals ( insertDataStandardDto.getChineseName () ) )
                || list1.stream ().anyMatch ( data -> data.getEnglishName ().equals ( insertDataStandardDto.getEnglishName () ) )) {
            return R.Failed ( StringConstant.INSERTFAILD );
        }
        boolean save = this.save ( dataStandard );
        if (save) {
            return R.Success ( StringConstant.INSERTSUCCESS );
        } else {
            return R.Failed ( StringConstant.INSERTFAILD );
        }
    }
    /**
     * 检查给定的dictId在dict_data表中是否存在
     */
    private boolean isDictIdValid(Long dictId) {
        // 假设有一个方法可以检查dictId是否存在
        DictData dictData = dictDataMapper.selectById ( dictId );
        return dictData != null;
    }

    @Override
    public R<DataStandard> updates(UpdateDataStandard updateDataStandard) {
        DataStandard dataStandard = new DataStandard ();
        List<DataStandard> list = this.list ();
        DataStandard one = this.getOne ( new LambdaQueryWrapper<DataStandard> ().eq ( DataStandard::getStandardCode, updateDataStandard.getStandardCode () ) );
        if (!(one.getStatus () == 0 || one.getStatus () == 2)) {
            return R.Failed ( StringConstant.UPDATEERRO );
        }
        if (list.stream ().anyMatch ( data -> data.getChineseName ().equals ( updateDataStandard.getChineseName () ) ) ||
                list.stream ().anyMatch ( data -> data.getEnglishName ().equals ( updateDataStandard.getEnglishName () ) )) {
            return R.Failed ( StringConstant.ERRO );
        }
        dataStandard.setUpdateTime ( LocalDateTime.now () );
        this.update ( dataStandard, new LambdaUpdateWrapper<DataStandard> ()
                .set ( DataStandard::getChineseName, updateDataStandard.getChineseName () )
                .set ( DataStandard::getEnglishName, updateDataStandard.getEnglishName () )
                .set ( DataStandard::getDescription, updateDataStandard.getDescription () )
                .set ( DataStandard::getInstitution, updateDataStandard.getInstitution () )
                .set ( DataStandard::getDataType, updateDataStandard.getDataType () )
                .set ( DataStandard::getValue, updateDataStandard.getValue () )
                .set ( DataStandard::getMin, updateDataStandard.getMin () )
                .set ( DataStandard::getMax, updateDataStandard.getMax () )
                .set ( DataStandard::getLength, updateDataStandard.getLength () )
                .set ( DataStandard::getDataAccuracy, updateDataStandard.getDataAccuracy () )
                .set ( DataStandard::getNotNull, updateDataStandard.getNotNull () )
                .set ( DataStandard::getDictName, updateDataStandard.getDictName () )
                .eq ( DataStandard::getStandardCode, updateDataStandard.getStandardCode () ) );
        return R.Success ( StringConstant.UPDATESUCCESS );
    }

    @Override
    public R<DataStandard> updatestatus(UpdateDataStandardStatusDto updateDataStandardStatusDto) {
        DataStandard dataStandard = new DataStandard ();
        BeanUtil.copyProperties ( updateDataStandardStatusDto, dataStandard );
        dataStandard.setUpdateTime ( LocalDateTime.now () );
        boolean update = this.update ( dataStandard, new LambdaUpdateWrapper<DataStandard> ().set ( DataStandard::getStatus, updateDataStandardStatusDto.getStatus () )
                .eq ( DataStandard::getStandardCode, updateDataStandardStatusDto.getStandardCode () )
                .eq ( DataStandard::getDeleted,0 ));
        if (update) {
            return R.Success ( StringConstant.UPDATESUCCESS );
        } else {
            return R.Failed ( StringConstant.UPDATEFAILED );
        }

    }

    @Override
    public R<DataStandard> delete(DeleteDataStandardDto deleteDataStandardDto) {
        DataStandard dataStandard = this.getOne ( new LambdaQueryWrapper<DataStandard> ().eq ( DataStandard::getStandardCode, deleteDataStandardDto.getStandardCode () ) );
        if (dataStandard.getStatus () == 0) {
            dataStandard.setDeleted ( (byte) 1 );
        } else {
            return R.Failed ( StringConstant.SYSTEMERROR );
        }
        this.saveOrUpdate ( dataStandard );
        return R.Success ( StringConstant.UPDATESUCCESS );
    }

    @Override
    public R<DataStandard> searchdetail(DeleteDataStandardDto deleteDataStandardDto1) {

        DataStandard one = this.getOne ( new LambdaQueryWrapper<DataStandard> ().eq ( DataStandard::getStandardCode, deleteDataStandardDto1.getStandardCode () ) );
        List<DataStandard> list = new ArrayList<> ();
        list.add ( one );
        return R.Success ( list );

    }

    @Override
    public R<Map<String, Object>> searchbydetail(SearchByDictNameDto searchByDictNameDto) {
        List<Map<String, Object>> searchbydetail = dataStandardMapper.searchbydetail ( searchByDictNameDto );
        if (searchbydetail == null || searchbydetail.isEmpty ()) {
            return R.Failed ( StringConstant.DICTNOTEXICTS );
        }
        // 处理第一个匹配的结果
        Map<String, Object> firstResult = searchbydetail.get ( 0 );
        // 创建一个Map来存储非空字段
        Map<String, Object> filteredData = new HashMap<> ();
        String dictName = null;
        for (Map.Entry<String, Object> entry : firstResult.entrySet ()) {
            if ("dictName".equals ( entry.getKey () )) {
                dictName = (String) entry.getValue ();
                continue; // 跳过dictName字段的直接添加
            }
            if (entry.getValue () != null && !String.valueOf ( entry.getValue () ).trim ().isEmpty ()) {
                filteredData.put ( entry.getKey (), entry.getValue () );
            }
        }
        // 构建最终响应
        Map<String, Object> responseMap = new HashMap<> ();
        if (dictName != null) {
            Map<String, Object> dictNameMap = new HashMap<> ();
            dictNameMap.put ( dictName, filteredData );
            responseMap.put ( "dictName", dictNameMap );
        } else {
            responseMap.put ( "dictName", filteredData ); // 如果没有dictName，则直接放入filteredData
        }
        // 返回成功响应
        return R.Success ( responseMap );
    }

    public R<DataStandard> updateStatusBatch(List<UpdateDataStandardStatusDto> updateDataStandardStatusDtos) {
        // 检查输入列表是否为空或null
        if (updateDataStandardStatusDtos == null || updateDataStandardStatusDtos.isEmpty()) {
            return R.Failed(StringConstant.DICTNOTEXISTS); // 修正了拼写错误
        }

        boolean allUpdatesSuccessful = true;

        for (UpdateDataStandardStatusDto dto : updateDataStandardStatusDtos) {
            // 查找是否存在未被删除的字典项
            DataStandard existingDict = this.getOne(new LambdaQueryWrapper<DataStandard>()
                    .eq(DataStandard::getStandardCode, dto.getStandardCode ())
                    .eq(DataStandard::getDeleted, 0)); // 假设0代表未删除

            if (existingDict == null) {
                // 如果找不到未被删除的字典项，标记为失败但继续尝试更新其他记录
                allUpdatesSuccessful = false;
                continue;
            }
            DataStandard dataStandard = new DataStandard ();
            dataStandard.setUpdateTime ( LocalDateTime.now () );
            // 执行更新操作
            boolean updateResult = this.update(new LambdaUpdateWrapper<DataStandard>()
                    .set(DataStandard::getStatus, dto.getStatus())
                    .eq(DataStandard::getStandardCode, dto.getStandardCode ()));

            if (!updateResult) {
                allUpdatesSuccessful = false;
            }
        }
        if (allUpdatesSuccessful) {
            return R.Success(StringConstant.UPDATESUCCESS);
        } else {
            return R.Failed("部分更新失败，可能是由于某些字典项已被删除或更新条件不匹配");
        }
    }
}




